package top.chatgqt.SmartChargeStation.netty.server.websocket;


import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
import io.netty.handler.timeout.IdleStateHandler;
import org.jetbrains.annotations.NotNull;
import top.chatgqt.SmartChargeStation.netty.server.handlers.ImoocServerHeartBeatHandler;
import top.chatgqt.SmartChargeStation.netty.server.handlers.ImoocWebSocketInboundHandler;
import top.chatgqt.SmartChargeStation.netty.server.handlers.ProtoMsgToMsgHandler;
import top.chatgqt.SmartChargeStation.netty.server.handlers.ProtobufHandler;
import top.chatgqt.SmartChargeStation.protocol.protobuf.ChargingCmdProtobuf;

import java.util.concurrent.TimeUnit;

/**
 * 自定义的通道初始化
 */
public class ImoocChannelInit extends ChannelInitializer<SocketChannel> {

    // 通道初始化
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        /*
        Channel初始化是伴随ChannelPipeline的初始化
        */

        //  获取 ChannelPipeline
        ChannelPipeline pipeline = socketChannel.pipeline();

        /*
        真正进行业务逻辑处理
         */
        pipeline
                // 监听超时
                .addLast(new IdleStateHandler(360, 360, 360, TimeUnit.SECONDS))
                // 自定义的超时处理
                .addLast(new ImoocServerHeartBeatHandler())
                /*
                Netty内置的协议编码解码器
                1. HttpServerCodec
                    Codec作为结尾，既可以做编码器，也可以做解码器
                2. HttpObjectAggregator
                3. WebSocketServerProtocolHandler
                    自动将http协议升级为WebSocket协议，自动完成握手过程，
                    以及后续数据帧的编码和解码
                 */

                // 对HTTP协议的解码
                .addLast(new HttpServerCodec())

                /*
                HTTP分为GET和POST
                    GET的参数在URL
                    POST的参数在Body
                HttpServerCodec只能解析URL的参数

                HttpObjectAggregator能够
                将HTTPMessage和HTTPContent合并为FullHttpRequest / FullHttpResponse
                 */

                // 处理HTTP的POST请求
                .addLast(new HttpObjectAggregator(65536))

                // 对WebSocket的协议进行解析
                .addLast(new WebSocketServerProtocolHandler("/ws"))

                /*
                通过消息类型的转换器，将WebSocketFrame转换为BinaryWebSocketFrame，
                将BinaryWebSocketFrame传到下一个处理器，也就是Protobuf处理器，去进行Protobuf序列数据的处理，
                处理后，再传到自定义业务逻辑处理器
                 */

                // 消息类型转换：将WebSocketFrame转换为BinaryWebSocketFrame
                .addLast(new ProtoMsgToMsgHandler())

                /*
                MessageLite: 轻量级的Message
                Message:

                是com.google.protobuf的两个类

                ChargingCmd.proto是Message类型，
                ChargingCmdProtobuf.ChargingCmd.getDefaultInstance()获取对应实例
                 */

                // (接收数据)Protobuf反序列化，返回Java对象
                .addLast(new ProtobufDecoder(ChargingCmdProtobuf.ChargingCmd.getDefaultInstance()))

                // (发送数据)Protobuf序列化
                .addLast(new ProtobufEncoder())

                /*
                自定义处理器
                 */
//                .addLast(new ImoocWebSocketInboundHandler())
                .addLast(new ProtobufHandler());
    }

}
